import os
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image

# 允许的图片文件扩展名
ALLOWED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']

def create_separate_pdfs(input_dir, output_dir, process_subfolders):
    """
    模式一：将每个图片文件转换为一个独立的PDF。
    """
    total_converted = 0

    # 定义一个内部函数来处理单个文件夹，避免代码重复
    def process_folder(current_input_dir, current_output_dir):
        if not os.path.isdir(current_input_dir):
            return 0
        
        if not os.path.exists(current_output_dir):
            os.makedirs(current_output_dir)

        converted_in_folder = 0
        for filename in os.listdir(current_input_dir):
            file_basename, file_extension = os.path.splitext(filename)
            
            if file_extension.lower() in ALLOWED_EXTENSIONS:
                input_path = os.path.join(current_input_dir, filename)
                output_path = os.path.join(current_output_dir, f"{file_basename}.pdf")

                try:
                    with Image.open(input_path) as img:
                        if img.mode != 'RGB':
                            img = img.convert('RGB')
                        img.save(output_path, "PDF", resolution=100.0)
                        converted_in_folder += 1
                        print(f"成功: {input_path} -> {output_path}")
                except Exception as e:
                    print(f"失败: 无法转换文件 '{input_path}'。错误: {e}")
        return converted_in_folder

    # 处理主文件夹
    total_converted += process_folder(input_dir, output_dir)

    # 如果勾选，处理子文件夹
    if process_subfolders:
        for item in os.listdir(input_dir):
            item_path = os.path.join(input_dir, item)
            if os.path.isdir(item_path):
                sub_output_folder = os.path.join(output_dir, item)
                total_converted += process_folder(item_path, sub_output_folder)
    
    return total_converted

def merge_images_to_pdf(input_dir, output_dir, output_filename, sort_order, process_subfolders):
    """
    模式二：将所有找到的图片合并到一个PDF文件中。
    """
    image_paths = []
    
    # 收集所有符合条件的图片路径
    if process_subfolders:
        for root, _, files in os.walk(input_dir):
            for file in files:
                if os.path.splitext(file)[1].lower() in ALLOWED_EXTENSIONS:
                    image_paths.append(os.path.join(root, file))
    else:
        for filename in os.listdir(input_dir):
            if os.path.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS:
                image_paths.append(os.path.join(input_dir, filename))

    if not image_paths:
        return 0

    # 根据选择的顺序排序
    image_paths.sort(reverse=(sort_order == 'desc'))

    # 打开所有图片并存入列表
    pil_images = []
    for path in image_paths:
        try:
            img = Image.open(path)
            if img.mode != 'RGB':
                img = img.convert('RGB')
            pil_images.append(img)
        except Exception as e:
            print(f"警告: 跳过无法打开的文件 '{path}'. 错误: {e}")

    if not pil_images:
        return 0

    # 保存为单一PDF
    first_image = pil_images[0]
    output_path = os.path.join(output_dir, output_filename)
    
    try:
        first_image.save(
            output_path, 
            "PDF", 
            resolution=100.0, 
            save_all=True, 
            append_images=pil_images[1:]
        )
        print(f"成功合并 {len(pil_images)} 张图片到: {output_path}")
        return len(pil_images)
    except Exception as e:
        messagebox.showerror("保存失败", f"无法保存合并的PDF文件。\n错误: {e}")
        return 0


def start_processing():
    """
    由“开始转换”按钮触发的主函数。
    """
    input_folder = input_folder_var.get()
    output_folder = output_folder_var.get()

    if not input_folder or not output_folder:
        messagebox.showerror("错误", "请先选择“源图片文件夹”和“PDF输出文件夹”！")
        return

    is_merge_mode = merge_var.get()
    process_subfolders = process_subfolders_var.get()
    
    if is_merge_mode:
        # 合并模式
        output_filename = output_filename_var.get()
        if not output_filename:
            messagebox.showerror("错误", "请输入合并后PDF的文件名！")
            return
        if not output_filename.lower().endswith('.pdf'):
            output_filename += '.pdf'
        
        sort_order = sort_order_var.get()
        count = merge_images_to_pdf(input_folder, output_folder, output_filename, sort_order, process_subfolders)
        messagebox.showinfo("处理完成", f"任务完成！\n\n总共合并了 {count} 张图片。")
    else:
        # 分开模式
        count = create_separate_pdfs(input_folder, output_folder, process_subfolders)
        messagebox.showinfo("处理完成", f"任务完成！\n\n总共成功转换了 {count} 个图片文件。")

def select_folder(folder_var, title):
    folder_selected = filedialog.askdirectory(title=title)
    if folder_selected:
        folder_var.set(folder_selected)

def toggle_merge_options():
    """根据是否勾选“合并模式”来启用/禁用相关选项"""
    if merge_var.get():
        sort_asc_radio.config(state='normal')
        sort_desc_radio.config(state='normal')
        output_filename_entry.config(state='normal')
    else:
        sort_asc_radio.config(state='disabled')
        sort_desc_radio.config(state='disabled')
        output_filename_entry.config(state='disabled')

# --- GUI ---
root = tk.Tk()
root.title("图片转PDF工具 Pro")
root.geometry("550x400")
root.resizable(False, False)

main_frame = tk.Frame(root, padx=20, pady=15)
main_frame.pack(expand=True, fill="both")

# --- 1. 文件夹选择 ---
folder_frame = ttk.LabelFrame(main_frame, text=" 1. 选择文件夹 ")
folder_frame.pack(fill="x", pady=(0, 10))

input_folder_var = tk.StringVar()
output_folder_var = tk.StringVar()

input_row = tk.Frame(folder_frame, pady=5)
input_row.pack(fill="x", padx=10)
ttk.Label(input_row, text="源图片文件夹:").pack(side="left")
ttk.Entry(input_row, textvariable=input_folder_var, state="readonly").pack(side="left", fill="x", expand=True, padx=5)
ttk.Button(input_row, text="浏览...", command=lambda: select_folder(input_folder_var, "请选择源图片文件夹")).pack(side="left")

output_row = tk.Frame(folder_frame, pady=5)
output_row.pack(fill="x", padx=10)
ttk.Label(output_row, text="PDF输出文件夹:").pack(side="left", anchor='w')
ttk.Entry(output_row, textvariable=output_folder_var, state="readonly").pack(side="left", fill="x", expand=True, padx=5)
ttk.Button(output_row, text="浏览...", command=lambda: select_folder(output_folder_var, "请选择PDF输出文件夹")).pack(side="left")

# --- 2. 模式与选项 ---
options_frame = ttk.LabelFrame(main_frame, text=" 2. 模式与选项 ")
options_frame.pack(fill="x", pady=10)

process_subfolders_var = tk.BooleanVar(value=True)
ttk.Checkbutton(options_frame, text="同时处理子文件夹", variable=process_subfolders_var).pack(anchor="w", padx=10, pady=5)

merge_var = tk.BooleanVar(value=False)
ttk.Checkbutton(options_frame, text="将所有图片合并为一个PDF (合并模式)", variable=merge_var, command=toggle_merge_options).pack(anchor="w", padx=10, pady=(10, 5))

# --- 合并模式的专属选项 ---
merge_options_frame = tk.Frame(options_frame, padx=20)
merge_options_frame.pack(fill="x")

# 排序
sort_order_var = tk.StringVar(value='asc')
sort_asc_radio = ttk.Radiobutton(merge_options_frame, text="按名称正序排列", variable=sort_order_var, value='asc')
sort_asc_radio.pack(anchor="w")
sort_desc_radio = ttk.Radiobutton(merge_options_frame, text="按名称倒序排列", variable=sort_order_var, value='desc')
sort_desc_radio.pack(anchor="w")

# 输出文件名
filename_row = tk.Frame(merge_options_frame, pady=5)
filename_row.pack(fill="x")
ttk.Label(filename_row, text="输出文件名:").pack(side="left")
output_filename_var = tk.StringVar(value="合并结果.pdf")
output_filename_entry = ttk.Entry(filename_row, textvariable=output_filename_var)
output_filename_entry.pack(side="left", fill="x", expand=True, padx=5)

# --- 3. 执行 ---
process_button = ttk.Button(main_frame, text="开始转换", command=start_processing)
process_button.pack(pady=10, fill="x", ipady=5)

# 初始化UI状态
toggle_merge_options()

root.mainloop()